import React, { PureComponent } from 'react'
import PropsTypes from 'prop-types'
import { Modal } from 'antd'

/**
 * form 的modal容器
 * 只需要定义一个基于antd的Form并使用此组件包裹
 * 就可以减少处理modal的逻辑
 * 只需要控制modal的出现，关闭和其他业务逻辑
 * ps：异步任务失败时modal保持打开状态
 * *********************示例**************************************
 * this.state={visible:false}
 * this.formRef = React.createRef()
 * <FormModal
 *    title=""
 *    formRef={this.formRef}
 *    visible={visible}
 *    asyncStatus={}
 *    onSaveForm={formValues=>{}}
 *    onClose={()=>{this.setState({visible:false})}}
 *  >
 *    <Form ref={this.fromRef}>
 * </FormModal>
 */

class FormModal extends PureComponent {
  constructor() {
    super()
    this.state = {
      visible: false,
      confirmLoading: false,
      lastPropVisible: undefined
    }
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    const { visible: nextVisible } = nextProps
    const { lastPropVisible } = prevState
    if (nextVisible !== lastPropVisible) {
      return {
        visible: nextVisible,
        lastPropVisible: nextVisible
      }
    }
    return null
  }

  componentDidUpdate(prevProps) {
    const { asyncStatus: prevAsyncStatus } = prevProps
    const { asyncStatus, asyncErrorCallback } = this.props

    // 异步提交成功，关闭modal
    if (prevAsyncStatus === 'pending' && asyncStatus === 'success') {
      this.onCancel()
    }

    // 异步提交失败，保持Modal
    if (prevAsyncStatus === 'pending' && asyncStatus === 'fail') {
      this.setState({ confirmLoading: false })
      if (asyncErrorCallback) {
        const form = this.props.formRef.current
        asyncErrorCallback(form.getFieldsValue())
      }
    }
  }

  onOk = () => {
    const form = this.props.formRef.current
    form.validateFields((err, values) => {
      if (err) {
        return
      }
      this.props.onSaveForm(values)

      // 如果是异步组件，提交按钮状态变为loading。同步直接关闭
      if (this.props.asyncStatus) {
        this.setState({ confirmLoading: true })
      } else {
        this.closeModal()
      }
    })
  }

  onCancel = () => {
    this.setState({
      visible: false,
      confirmLoading: false
    })
    this.props.onClose()
  }

  render() {
    const { className, title, footer, otherProps } = this.props
    const { visible, confirmLoading } = this.state
    return (
      <div className={`FormModal ${className}`}>
        <Modal
          title={title}
          className="FormModalBCFX"
          visible={visible}
          onOk={this.onOk}
          onCancel={this.onCancel}
          confirmLoading={confirmLoading}
          destroyOnClose
          {...otherProps}
          {...(footer || {})}>
          {this.props.children}
        </Modal>
      </div>
    )
  }
}

FormModal.propTypes = {
  className: PropsTypes.string,
  title: PropsTypes.string,
  visible: PropsTypes.bool,
  onSaveForm: PropsTypes.func,
  asyncStatus: PropsTypes.oneOf(['pending', 'success', 'fail']),
  asyncErrorCallback: PropsTypes.func,
  formRef: PropsTypes.object,
  onClose: PropsTypes.func
}

export default FormModal
